#ifndef GRID_HPP
#define GRID_HPP

////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <string>

#include <SFML/System/Vector2.hpp>

#include <SmegTools/Config.h>

#ifdef _DEBUG
namespace sf {
    class RenderWindow;
}
#endif

#include <SmegTools/Debug/DebugNew.hpp>

////////////////////////////////////////////////////////////
/// Defines
////////////////////////////////////////////////////////////
#define DEFAULT_GRID_WIDTH 1024
#define DEFAULT_GRID_HEIGHT 768

namespace smeg {
    namespace ai {

////////////////////////////////////////////////////////////
/// Describe the grid for the pathfinding
////////////////////////////////////////////////////////////
class Grid
{
public:
    ////////////////////////////////////////////////////////////
    /// Constructor/Destructor
    ////////////////////////////////////////////////////////////
                    Grid( unsigned _uWidth = DEFAULT_GRID_WIDTH, unsigned _uHeight = DEFAULT_GRID_HEIGHT, unsigned _uCellSize = 1 );
                    ~Grid();

    ////////////////////////////////////////////////////////////
    /// Load the grid from an image file
    ///
    /// \param _Filename : Filename to a black & white image
    ///
    ////////////////////////////////////////////////////////////
    void            LoadFromImage( const std::string& _Filename );

    ////////////////////////////////////////////////////////////
    /// Mark a point as blocked/unblocked
    ////////////////////////////////////////////////////////////
    bool            IsBlocked( int _fX, int _fY, bool _bNeedConvert = false ) const;
    void            MarkAsBlocked( int _fX, int _fY, bool _bNeedConvert = false );
    void            MarkAsUnblocked( int _fX, int _fY, bool _bNeedConvert = false );
    void            ToggleObstacle( int _fX, int _fY, bool _bNeedConvert = false );
    void            RemoveAllObstacles();

    ////////////////////////////////////////////////////////////
    /// Convert a point from grid to world/world to grid space
    ////////////////////////////////////////////////////////////
    void            ConvertToGridSpace( int _fX, int _fY, sf::Vector2i& _OutPoint ) const;
    void            ConvertToWorldSpace( int _fX, int _fY, sf::Vector2f& _OutPoint ) const;

    /*********************** Accessors ************************/
    unsigned        GetCellSize() const;
    unsigned        GetNumCells() const;
    bool            IsValid( int _iX, int _iY ) const;

private:
    /******************* Protected members ********************/
    sf::Vector2i    m_Cells;
    
    unsigned        m_uCellSize;
    unsigned        m_uNumCells;
    bool*           m_pGrid;

#ifdef _DEBUG
public:
    void            DebugRender( sf::RenderWindow* _pRenderWindow, bool _bDisplayObstacles = false );
#endif
};

/************************ Inline **************************/
inline unsigned Grid::GetCellSize() const {
    return m_uCellSize;
}

inline unsigned Grid::GetNumCells() const {
    return m_uNumCells;
}

    } // namespace ai
} // namespace smeg

#include <SmegTools/Debug/DebugNewOff.hpp>

#endif // GRID_HPP
